package com.kaigejava.rulesengine.engine.core.kie;


import com.alibaba.fastjson.JSON;
import org.apache.commons.collections.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author kaigejava
 * @des:RulesEngine system mapper module,for faster getting rules
 */
public class RulesMapper {

    /**
     * ruleType -> rules
     */
    private static final Map<Integer, CopyOnWriteArrayList<CompiledRule>> RULES = new ConcurrentHashMap<Integer, CopyOnWriteArrayList<CompiledRule>>();
    private static final Map<Integer, String> RULE_NAMES = new ConcurrentHashMap<Integer, String>();

    public static Map<Integer, CopyOnWriteArrayList<CompiledRule>> getRules() {
        return RULES;
    }

    public static String getRulesJson() {
        return JSON.toJSONString(getRules());
    }

    /**
     * add rule to mapper
     *
     * @param ruleId
     * @param ruleType represent  business type(hava same fact struct)
     * @param content  rule string reprsent
     */
    public static void addRule(Integer ruleId, Integer ruleType, String content) {
        CompiledRule compiledRule = buildCompileRule(ruleId, ruleType, content);
        CopyOnWriteArrayList<CompiledRule> rules = RULES.get(ruleType);
        if (rules == null) {
            rules = new CopyOnWriteArrayList<CompiledRule>();
            rules.add(compiledRule);
            RULES.put(ruleType, rules);
        } else {
            rules.add(compiledRule);
        }

    }

    private static CompiledRule buildCompileRule(Integer ruleId, Integer ruleType, String content) {
        CompiledRule compiledRule = new CompiledRule();
        compiledRule.setRuleId(ruleId);
        compiledRule.setRuleType(ruleType);
        compiledRule.setContent(content);
        return compiledRule;
    }

    public static void deleteRule(Integer ruleId, Integer ruleType) {
        List<CompiledRule> compiledRules = RULES.get(ruleType);
        if (CollectionUtils.isNotEmpty(compiledRules)) {
            for (CompiledRule compiledRule : compiledRules) {
                if (compiledRule.getRuleId().equals(ruleId)) {
                    compiledRules.remove(compiledRule);
                    break;
                }
            }
        }
    }

    public static void resetRules() {
        RULES.clear();
    }

    private static final Map<String, String> LUA_FUNCTIONS = new HashMap<String, String>();

    public static void addFunction(String funName, String script) {
        LUA_FUNCTIONS.put(funName, script);
    }

    public static String getScript(String funName) {
        return LUA_FUNCTIONS.get(funName);
    }

    public static void addRuleName(Integer ruleId, String name) {
        RULE_NAMES.put(ruleId, ruleId + "_" + name);
    }

    public static String getRuleName(Long ruleId) {
        return RULE_NAMES.get(ruleId);
    }
}
